package com.neutech.maplestory.entity;

import com.neutech.maplestory.client.MapleStoryClient;
import com.neutech.maplestory.constant.Constant;
import com.neutech.maplestory.util.ImageUtil;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;

/** （10）
 * @author ZZQ
 * @PackageName: com.neutech.maplestory.entity
 * @ClassName: Hero
 * @Description:
 * @date 2021/1/27 17:33
 */
public class Hero extends AbstractMapleStoryObject {
    public static Image[] imgs = new Image[100];

    static {
        for (int i = 0; i < 4; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_stand" + i);
        }
        for (int i = 4; i < 8; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_stand" + (i - 4));
        }
        for (int i = 8; i < 13; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_walk" + (i - 8));
        }
        for (int i = 13; i < 18; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_walk" + (i - 13));
        }
        imgs[18] = ImageUtil.getImage("hero_right_prone");
        imgs[19] = ImageUtil.getImage("hero_left_prone");
        imgs[20] = ImageUtil.getImage("hero_right_jump");
        imgs[21] = ImageUtil.getImage("hero_left_jump");

        for (int i = 22; i < 26; i++) {
            imgs[i] = ImageUtil.getImage("hero_right_shoot" + (i - 22));
        }
        for (int i = 26; i < 30; i++) {
            imgs[i] = ImageUtil.getImage("hero_left_shoot" + (i - 26));
        }
        imgs[30] = ImageUtil.getImage("blood");
        imgs[31] = ImageUtil.getImage("blood01");
        imgs[32] = ImageUtil.getImage("boold2");

    }

    public MapleStoryClient msc;

    public Hero() {
    }

    public int MP;

    public int MAX_MP = 1000;//人物魔法值上限

    public int HP;

    public int MAX_HP = 1000;//人物血量上限

    public int Experience;

    public int MAX_Experience = 1000;
    /**
     * 基础攻击力
     */
    public int ATT;
    /**
     * 伤害值
     */
    public int hitValue;

    public Random r = new Random();

    public Hero(MapleStoryClient msc, int x, int y) {
        this.msc = msc;
        this.x = x;
        this.y = y;
        this.MP = MAX_MP;
        this.HP = MAX_HP;
        this.Experience = 0;
        this.ATT = 1000;
//        this.hitValue = r.nextInt(ATT - 5) + 8;//取值范围8~12
        this.speed = Constant.HERO_SPEED;
        this.width = imgs[0].getWidth(null);
        this.height = imgs[0].getHeight(null);
        this.dir = Direction.RIGHT;
        this.action = Action.STAND;
    }

    /**
     * 一直加的计数器
     */
    public int count = 0;
    /**
     * 计算当前画第几张图
     */
    private int step = 0;
    /**
     * 左右的开关
     */
    public boolean left, right, down, jump, shoot, pickup,moveup;

//    public static Random a = new Random();
//    private boolean hit(Mob mob){
//        if(this.live && this.getRectangle().intersects(mob.getRectangle()) && mob.action != Action.DIE){
//            msc.mobs.get(1).hitValue = (int) (msc.mobs.get(1).ATT *(1 + a.nextDouble()));//1~2倍
//            //创建出伤害值
//            Power power = new Power(msc,mob.x,mob.y);
//            msc.powers.add(power);
//            this.HP -= power.value;
//        }return true;
//    }

    private int time = 0;
    private boolean d = true;
    public void hurt(List<Mob> mobs) {
        for (int i = 0; i < mobs.size(); i++) {
            Mob a = mobs.get(i);
            if (this.getRectangle().intersects(a.getRectangle()) && d == true) {
                this.HP -= 100;
                d = false;
            }
        }

        switch (time){
            case 80:
                d = true;
                time = 0;
                break;
            default:
                time++;
                break;
        }
    }

    @Override
    public void draw(Graphics g) {
        switch (dir) {
            case RIGHT:
                switch (action) {
                    case STAND:
                        //right stand
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[step++ % 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //right stand

                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 8], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 8], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[18], x - 8, y + 32, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[20], x, y, null);
                        break;
                    case SHOOT:
                        //right shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 22], x, y, null);
                        } else {
                            g.drawImage(imgs[(step % 4) + 22], x, y, null);
                        }
                        break;
                    case UP:
                        g.drawImage(imgs[20],x,y,null);
                        break;
                    default:
                        break;
                }
//                //right stand
//                if(count ++ % 3 == 0){
//                    g.drawImage(imgs[step ++ % 4],x,y,null);
//                }else{
//                    g.drawImage(imgs[step % 4],x,y,null);
//                }
                break;
            case LEFT:
                switch (action) {
                    case STAND:
                        //left stand

                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 4], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 4 + 4], x, y, null);
                        }
                        break;
                    case WALK:
                        //left stand

                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 5) + 13], x, y, null);
                        } else {
                            g.drawImage(imgs[step % 5 + 13], x, y, null);
                        }
                        break;
                    case PRONE:
                        g.drawImage(imgs[19], x - 8, y + 32, null);
                        break;
                    case JUMP:
                        g.drawImage(imgs[21], x, y, null);
                        break;
                    case SHOOT:
                        //left shoot
                        if (count++ % 3 == 0) {
                            g.drawImage(imgs[(step++ % 4) + 26], x, y, null);
                        } else {
                            g.drawImage(imgs[(step % 4) + 26], x, y, null);
                        }
                        break;
                    case UP:
                        g.drawImage(imgs[21],x,y,null);
                        break;
                    default:
                        break;
                }
//                //right stand
//
//                if(count ++ % 3 == 0){
//                    g.drawImage(imgs[(step ++ % 4) + 4],x,y,null);
//                }else{
//                    g.drawImage(imgs[step % 4 + 4],x,y,null);
//                }
                break;

            default:
                break;
        }
//        //right stand
//        if(count ++ % 3 == 0){
//        g.drawImage(imgs[step ++ % 4],x,y,null);
//    }else{
//            g.drawImage(imgs[step % 4],x,y,null);
//        }
        hurt(msc.mobs);
        experienceBar.draw(g);
        mpBar.draw(g);
        bloodBar.draw(g);
        move();
    }

    @Override
    public void move() {
        if (left) {
            x -= speed;
            this.action = Action.WALK;
        }
        if (right) {
            x += speed;
            this.action = Action.WALK;
        }
        if (moveup && !left && !right) {
            y -= speed;
            this.action = Action.UP;
        }else{
            moveup = false;
        }

        if (jump) {
            jump(msc.grounds);
        } else if (moveup && !left && !right){

        }else{
            moveup = false;
            //自由落体（往下掉）
            jumpdown(msc.grounds);
        }
        if (shoot) {
            shoot();
        }
        if (pickup) {
            pickup(msc.items);
        }

//        if(shoot){
//            this.action = Action.SHOOT;
//        }
//        if(down){
//            this.action = Action.PRONE;
//        }
        confirmStatus();
        outOfBound();
    }

    /**
     * 射击持续时长的变量
     */
    private int shootcount = 0;

    /**
     * 射击的方法
     */
    private void shoot() {
        shootcount++;
//        this.MP -= 5;

        if (shootcount % 3 == 0) {
//            this.hitValue = r.nextInt(ATT - 5) + 8;//取值范围8~12
            shoot = false;
            this.MP -= 5;
            Arrow arrow;
            if (dir == Direction.RIGHT) {
                arrow = new Arrow(msc, x + width, y + height / 2 + 8, dir);
            } else {
                arrow = new Arrow(msc, x, y + height / 2 + 8, dir);
            }

            msc.arrows.add(arrow);

        }
    }


    private double v0 = Constant.INIT_JUMP_SPEED;
    private double vt;
    private double g = 9.8;
    private double delta_height;
    private double t = 0.5;

    /**
     * 跳跃的方法
     */
    public void jump(List<Ground> grounds) {
        if (!drop) {
            vt = v0 - g * t;
            delta_height = v0 * t;
            v0 = vt;
            y -= delta_height;
            //什么时候往下掉
            if (vt <= 0) {
                vt = 0;
                drop = true;
            }
        } else {
            jumpdown(grounds);
        }
        //向上跳（竖直上抛过程）

//        for (int i = 0;i < grounds.size();i ++){
//        Ground ground = grounds.get(i);
//        if(this.getRectangle().intersects(ground.getRectangle())){
//            //跳
//            if (this.y >= ground.y - this.height){
//                this.y = ground.y - this.height;
//            }
//        }
//        }
    }

    private boolean drop = true;

    public void jumpdown(List<Ground> grounds) {
        //掉的过程（自由落体）
        vt = v0 + g * t;
        delta_height = v0 * t;
        v0 = vt;
        y += delta_height;
        //什么时候停止自由落体
        for (int i = 0; i < grounds.size(); i++) {
            Ground ground = grounds.get(i);
            if (this.getRectangle().intersects(ground.getRectangle()) && this.y <= ground.y - this.height + 40) {
                //加40 是40ms的距离不做碰撞检测 可掉出地图
                //停了

                if (this.y >= ground.y - this.height) {
                    this.y = ground.y - this.height;
                    drop = false;
                    jump = false;
                    v0 = Constant.INIT_JUMP_SPEED;
                    vt = 0.0;
                    break;
                }
            } else {
                drop = true;
            }
        }

    }

    /*private void jump() {
//        // vt - v0 + gt 竖直上抛
        vt = v0 - g * t;
        delta_height = v0 * t;
        v0 = vt;
        y -= delta_height;
        // 自由落体的结束位置
        if (y >= 600) {
            jump = false;
            v0 = Constant.INIT_JUMP_SPEED;
            vt = 0.0;
            y = 600;
        }
    }*/

    /**
     * 根据当前人物的左右开关，确定人物的方向
     */
    private void confirmStatus() {
        if (left && !right) {
            this.dir = Direction.LEFT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (right && !left) {
            this.dir = Direction.RIGHT;
            if (jump) {
                this.action = Action.JUMP;
            }
        } else if (jump) {
            this.action = Action.JUMP;
        } else if (down) {
            this.action = Action.PRONE;
        } else if (shoot) {
            this.action = Action.SHOOT;
        } else if(moveup) {
            this.action = Action.UP;
        }
        //都按下或者都不按下
        else {
            this.action = Action.STAND;
        }

    }

    /**
     * 按键的方法
     *
     * @param e 键盘事件对象
     */
    public Ground rope = new Ground(this.msc,450,485,50,200);
    public Ground rope1 = new Ground(this.msc,600,285,50,125);
    public Ground rope2 = new Ground(this.msc,500,160,50,200);
    public Ground rope3 = new Ground(this.msc,840,160,40,200);
    public void KeyPressed(KeyEvent e) {
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
//                x -= speed;
                left = true;
                break;
            case KeyEvent.VK_W:
                if(this.getRectangle().intersects(rope.getRectangle())
                        || this.getRectangle().intersects(rope1.getRectangle())
                || this.getRectangle().intersects(rope2.getRectangle())
                || this.getRectangle().intersects(rope3.getRectangle())){
                    moveup = true;
                    drop = false;
                }else{
                    moveup = false;
                    drop = true;
                }
                break;
            case KeyEvent.VK_D:
//                x += speed;
                right = true;
                break;
//            case KeyEvent.VK_S:
//                y += speed;
//                break;
            case KeyEvent.VK_S:
                down = true;
                break;
            case KeyEvent.VK_K://跳跃
                jump = true;
                break;
            case KeyEvent.VK_J://射击
                shoot = true;
                break;
            case KeyEvent.VK_L://拾取
                pickup = true;
                break;
//            case KeyEvent.VK_I://道具包
//
//                break;
            default:
                break;
        }
    }

    /**
     * 释放按键的方法
     *
     * @param e 键盘事件
     */
    public void keyReleased(KeyEvent e) {
//                System.out.println("抬起");
//                if(e.getKeyCode() == KeyEvent.VK_S){
//                    System.out.println("抬起");
//                }
        switch (e.getKeyCode()) {
            case KeyEvent.VK_A:
                left = false;
                break;
            case KeyEvent.VK_W:
                moveup = false;
                break;
            case KeyEvent.VK_D:
                right = false;
                break;
//            case KeyEvent.VK_S:
//                break;
            case KeyEvent.VK_S:
                down = false;
                break;
//            case KeyEvent.VK_J:
//                shoot = false;
//                break;
            case KeyEvent.VK_L://拾取
                pickup = false;
                break;
            default:
                break;
        }
    }

    private void outOfBound() {
        if (this.x <= 0) {
            this.x = 0;
        }
        if (this.x >= Constant.GAME_WIDTH - this.width) {
            this.x = Constant.GAME_WIDTH - this.width;
        }
        if (this.dir == Direction.RIGHT) {
            if (this.x >= 640 - this.width && this.y >= 635 - this.height + 40 ) {
                this.x = 640 - this.width;
            }
            if (this.x >= 740 - this.width && this.y >= 585 - this.height + 40) {
                this.x = 740 - this.width;
            }
//            if (this.x >= 400 - this.width && this.y >= 550 - this.height + 40 && this.x <= 800 - this.width) {
//                this.x = 400 - this.width;
//            }
        }

        if (this.dir == Direction.LEFT) {
            if (this.x <= 350 && this.y >= 635 - this.height + 40 ) {
                this.x = 350;
            }
        }
//            if(this.x <= 800 && this.y >= 550 - this.height + 40 && this.x >= 400 - this.width){
//                this.x = 800;
//            }
//        }

    }

    /**
     * 拾取道具的方法
     *
     * @param item 被拾取的道具对象
     * @return 是否捡到道具
     */
    private boolean pickup(Item item) {
        if (item.live && this.getRectangle().intersects(item.getRectangle())) {
            item.live = false;
            //存放之前和道具包里面的每一个进行判断

            for (int i = 0; i < msc.itemPackage.items.size(); i++) {
                Item itm = msc.itemPackage.items.get(i);
                //如果相同数量+1
                if (item.type == itm.type) {
                    itm.qty += 1;
                    return false;
                }
            }
            //业务 放入道具包
            msc.itemPackage.items.add(item);//捡起的掉落道具
//            msc.items.add(item);//掉落的所有道具

//            //被吃掉之后的业务
//            switch (item.type) {
//                case 0:
//                    this.HP += 50;
//                    break;
//                case 1:
//                    this.HP += 100;
//                    break;
//                case 2:
//                    this.HP += 300;
//                    break;
//                case 3:
//                    this.MP += 100;
//                    break;
//                default:
//                    break;
//            }
//            if(HP >= MAX_HP){
//                HP = MAX_HP;
//            }
//            if (MP >= MAX_MP){
//                MP = MAX_MP;
//            }

//            item.live = false;
        }
        return false;
    }

    /**
     * 拾取一堆道具
     *
     * @param items 道具容器
     * @return 是否拾取到
     */
    public boolean pickup(List<Item> items) {
        for (int i = 0; i < items.size(); i++) {
            Item item = items.get(i);
            if (pickup(item)) {
                return true;
            }
        }
        return false;
    }

    //HP管
    public BloodBar bloodBar = new BloodBar();

    class BloodBar extends AbstractMapleStoryObject {
        //        public BloodBar(){}
        private Image img;

        public BloodBar() {
            this.img = ImageUtil.getImage("blood");
            this.width = img.getWidth(null);
//            this.width = Mob.this.width;
//            this.height = 10;
        }

        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width / this.width * Hero.this.HP / Hero.this.MAX_HP;
            for (int i = 0; i < n; i++) {
                g.drawImage(Hero.this.imgs[30], Hero.this.x + (i * this.width), Hero.this.y - 15, null);
            }
        }
    }

    //MP管
    public MpBar mpBar = new MpBar();

    class MpBar extends AbstractMapleStoryObject {
        //        public BloodBar(){}
        private Image img;

        public MpBar() {
            this.img = ImageUtil.getImage("blood01");
            this.width = img.getWidth(null);
//            this.width = Mob.this.width;
//            this.height = 10;
        }

        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width / this.width * Hero.this.MP / Hero.this.MAX_MP;
            for (int i = 0; i < n; i++) {
                g.drawImage(Hero.this.imgs[31], Hero.this.x + (i * this.width), Hero.this.y - 25, null);
            }
        }
    }
    //经验管
    public ExperienceBar experienceBar = new ExperienceBar();

    class ExperienceBar extends AbstractMapleStoryObject {
        //        public BloodBar(){}
        private Image img;

        public ExperienceBar() {
            this.img = ImageUtil.getImage("boold2");
            this.width = img.getWidth(null);
//            this.width = Mob.this.width;
//            this.height = 10;
        }

        @Override
        public void draw(Graphics g) {
            int n = Hero.this.width / this.width * Hero.this.Experience / Hero.this.MAX_Experience;
            for (int i = 0; i < n; i++) {
                g.drawImage(Hero.this.imgs[32], Hero.this.x + (i * this.width), Hero.this.y - 35, null);
            }
        }
    }
}


